//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<ctrl_edit.h>
///	@path	~/src/appear/ctrl/
///	@date	2007/12/14
///	@desc	Simple edit control implementation.

#pragma once

#include "xeres.h"

#include "lib/math/rect.h"
#include "lib/utilities/string.h"
#include "lib/system/lock.h"

#include "graphics/IFont.h"

#include "gui/style/uniscribe.h"
#include "gui/composite/layer.h"
#include "gui/input/input.h"

#include "appear/app/key_map.h"
#include "appear/app/cmd_op.h"

namespace xeres {

	/*!
		\class	CtrlEdit
		\brief	Simple edit control implementation, both for UI or DX.
	*/
	class CtrlEdit
	{
	public:

		/// \ctor
		CtrlEdit( void );

		/// \dtor
		~CtrlEdit( void );

	//@ messages
		HandleInput OnMouseInput( const MouseInput& input , int x , int y );

		void OnSetFocus( void );
		void OnKillFocus( void );
		void OnLMBDown( uint32 status , int x , int y );
		void OnLMBUp( void );
		void OnLMBDblClk( void );
		void OnMouseLeave( void );
		void OnMouseMove( uint32 status , int x , int y );
		bool OnKeyDown( const KeyInput& input );

		void OnPaint( Layer& layer );
		void OnCtrlSize( const Rect<int>& rect );

		/*!
			\brief		Set DX used font, for DX rendering.
		*/
		void SetFont( RefWeak<IFont> font );

		/*!
			\brief		Set control edit as password.
		*/
		void SetPassword( void );

		/*!
			\brief		Select all text.
		*/
		void SelectAll( void );

		/*!
			\brief
		*/
		void SetCaretTimer( void );

		/*!
			\brief		Clear entered text.
		*/
		void ClearText( void );

		/*!
			\brief		Set editing text.
		*/
		void SetText( const WString& text , bool bSelected );

		/*!
			\brief		Copy selected text to clipboard.
		*/
		void CopyToClipboard( void );

		/*!
			\brief		Paste text from clipboard.
		*/
		void PasteFromClipboard( void );

		/*! 
			\brief		Cut & copy to clipboard.
		*/
		void Cut( void );

		/*!
			\brief		Get text rectangle.
		*/
		void GetRectText( RECT& rcText );

		/*!
			\brief		Place caret at specific position.
		*/
		void PlaceCaret( int nCP );

		/*!
			\brief		Delete selection text.
		*/
		void DeleteSelectionText( void );

		/*!
			\brief
		*/
		void ResetCaretBlink( bool ResetTimer = false );

		/*!
			\brief		Get control text.
		*/
		const WString& GetText( void ) const { return m_buffer.GetString(); }

		/*!
			\brief		Get edit rect.
		*/
		const Rect<int>& GetRect( void ) { return m_rect; }

		/*!
			\brief		Need control update.
		*/
		bool NeedUpdate( void ) const { return m_needUpdate; }

	private:

		// internal process character input
		bool ProcessInput( const KeyInput &input );

		// Get uniscribe instance.
		Uniscribe& GetUniscribe( void ) { return m_buffer; }

		// get region of text
		inline int TextLeft( void ) const;
		inline int TextTop( void ) const;
		inline int TextRight( void ) const;
		inline int TextBottom( void ) const;

	//@ data

		ThreadLock		m_lock;
		Rect<int>		m_rect;			// rectangle in parent space
		HFONT			m_font;
		Uniscribe		m_buffer;		// Buffer to hold text

		int      		m_nBorder;      // Border of the window
		int      		m_nSpacing;     // Spacing between the text and the edge of border
		int      		m_nCaret;       // Caret position, in characters
		int      		m_nSelStart;    // Starting position of the selection. The caret marks the end.
		int      		m_nFirstVisible;// First visible character in the edit control

		bool     		m_bCaretOn;     // Flag to indicate whether caret is currently visible
		bool			m_bEntered;		// mouse entered control
		bool     		m_bInsertMode;  // If true, control is in insert mode. Else, overwrite mode.
		bool			m_bMenuLoop;	// inside menu loop

		bool			m_bActive;		// active
		bool			m_bMouseDrag;	// True to indicate drag in progress
		bool			m_bHideCaret;	// If true, we don't render the caret.
		bool			m_isPassword;	// is a password edit control

		bool			m_needUpdate;	// render has been modified, need update
		bool			m_spare0[3];

		// short cut map
		KeyMap			m_hotkey;
	};

} // namespace xeres
